package com.itcanteen.medical.patient.service.impl;

import com.itcanteen.medical.patient.entity.Doctor;
import com.itcanteen.medical.patient.entity.DoctorLevel;
import com.itcanteen.medical.patient.entity.Patient;
import com.itcanteen.medical.patient.entity.RegistrationRecording;
import com.itcanteen.medical.patient.mapper.DoctorLevelMapper;
import com.itcanteen.medical.patient.mapper.DoctordMapper;
import com.itcanteen.medical.patient.mapper.PatientMapper;
import com.itcanteen.medical.patient.mapper.RecordingMapper;
import com.itcanteen.medical.patient.service.RecordingService;
import com.itcanteen.medical.patient.util.AbstractLock;
import com.itcanteen.medical.patient.util.HighPerformanceZkLock;
import com.itcanteen.medical.patient.util.IdWorker;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
public class RecordingServiceImpl implements RecordingService {

    @Autowired
    @SuppressWarnings("all")
    private RecordingMapper recordingMapper;

    @Autowired

    private IdWorker idWorker;

    @Autowired
    @SuppressWarnings("all")
    private DoctordMapper doctorMapper;

    @Autowired
    @SuppressWarnings("all")
    private PatientMapper patientMapper;

    @Autowired
    @SuppressWarnings("all")
    private DoctorLevelMapper doctorLevel;

    @Autowired
    private RedisTemplate redisTemplate;


    @Override
    public List<RegistrationRecording> findAll() {
        return recordingMapper.selectAll();
    }


    @Override
    public int add(RegistrationRecording recording) {
        //自动生成id
        recording.setId(idWorker.nextId());
        //转换成字符串
        Long id = recording.getId();
        String recordingById = id.toString();

        //高并发下的分布锁
        AbstractLock highPerformanceZkLock = new HighPerformanceZkLock();
        //进行加锁
        highPerformanceZkLock.getLock(recordingById);

        //进行挂号生成
        recording.setId(new Long(recordingById));
        recording.setStatus("0");
        recording.setCreateTime(new Date());
        Long doctorId = recording.getDoctorId();
        Doctor doctor = doctorMapper.findById(doctorId);
        //医生看病结束时间
        Date visitendTime = doctor.getVisit_end_time();
        long endTime = visitendTime.getTime();
        //医生看病开始时间
        Date visitstartTime = doctor.getVisit_start_time();
        long startTime = visitstartTime.getTime();
        //看病当前时间
        Date date = new Date();
        long currentTime = date.getTime();
        //insert>0是添加成功
        int insert = 0;
        //判断时间是否符合看病时间
        if (startTime < currentTime && currentTime < endTime) {
            insert = recordingMapper.insert(recording);
        } else {
            throw new NullPointerException("医生以下班");
        }
        //挂号成功
        if (insert > 0) {
            //获取挂号价格
            Long levelId = doctor.getLevel_id();
            DoctorLevel doctorLeve = doctorLevel.findById(levelId);
            Double price = doctorLeve.getPrice();
            //患者ID
            Long patientId = recording.getPatientId();
            //查看lock是否有值
            Long lock = (Long) redisTemplate.opsForValue().get("lock");

            //设置伐值
            boolean flag = false;
            if (lock == null) {
                //当前时间
                Integer time = 30;
                //最大时间
                Integer maxtime = 60;

                Patient patient =null;
                while (true){
                    time = time+1;
                    //给赋完的值加入过期时间
                    redisTemplate.opsForValue().set("lock", patientId, time, TimeUnit.SECONDS);

                    if (time>maxtime){
                        redisTemplate.delete("lock");
                    }

                    //获取锁
                    Long getLock = (Long) redisTemplate.opsForValue().get("lock");

                    /*System.out.println("dfsdgfg========="+getLock);

                    long lockId = getLock.longValue();*/

                    patient = patientMapper.findById(getLock);
                    break;
                }



                //判断用户钱是否够足够
                if (price <= patient.getBalance()) {
                    //用户钱足够
                    patient.setBalance(patient.getBalance() - price);
                    patientMapper.updateByPrimaryKey(patient);
                    //释放锁
                    redisTemplate.delete("lock");
                    //开启法值
                    flag = true;
                } else {
                    //用户钱不够挂号失效
                    recording.setStatus("1");
                    recordingMapper.updateByPrimaryKey(recording);
                }
            }

            if (flag) {
                //医生余额+钱
                doctor.setBalance(doctor.getBalance() + price);
                doctorMapper.updateByPrimaryKey(doctor);
            }
        }
        try {
            Thread.sleep(30);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        highPerformanceZkLock.releaseLock();
        return insert;
    }
    }
